<link rel="import" href="../bower_components/polymer/polymer-element.html">
<link rel="import" href="../bower_components/vaadin-material-theme/vaadin-combo-box.html">
<link rel="import" href="../bower_components/paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="../bower_components/iron-ajax/iron-ajax.html">
<link rel="import" href="view-app.html">
<link rel="import" href="style/shared-styles.html">
<!-- import external library -->
<link rel="import" href="../lib/imask.html">
<dom-module id="view-settings">
  <template>
    <style include="shared-styles app-grid-style">
      :host {
        display: block;
        padding: 10px;
        --app-grid-item-height: 50%;
      }

      .card {
        min-height: 450px;
      }

      .switch {
        padding: 16px 0;
      }

      .meta-data>p {
        padding: 5px 0;
      }

      @media (min-width: 360px) and (max-width: 768px) {
        :host {
          --app-grid-columns: 1;
        }
      }

      @media (min-width: 769px) and (max-width: 1024px) {
        :host {
          --app-grid-columns: 1;
        }
      }

      @media (min-width: 1025px) and (max-width: 1200px) {
        :host {
          --app-grid-columns: 2;
        }
      }

      @media (min-width: 1201px) {
        :host {
          --app-grid-columns: 3;
        }
      }
    </style>
    <firebase-auth app-name="smart-mes" id="auth" user="{{user}}"></firebase-auth>
    <firebase-query app-name="smart-mes" id="appRoot" path="/data"></firebase-query>
    <firebase-document app-name="smart-mes" id="appData" path="/data/[[userdata.key]]" data="{{appdata}}"></firebase-document>
    <firebase-document app-name="smart-mes" id="userData" path="/user/[[user.uid]]" data="{{userdata}}"></firebase-document>
    <firebase-document app-name="smart-mes" id="userToken" path="/user/[[user.uid]]/token" data="[[token]]"></firebase-document>
    <firebase-document app-name="smart-mes" id="factoryOrderIndex" path="/data/[[userdata.key]]/factoryData/order" data="[[factoryOrderIndex]]"></firebase-document>
    <firebase-document app-name="smart-mes" id="appNotification" path="/data/[[userdata.key]]/appData/notification" data="[[notification]]"></firebase-document>
    <firebase-document app-name="smart-mes" id="appEmailAlert" path="/data/[[userdata.key]]/appData/email_alert" data="[[emailAlert]]"></firebase-document>
    <firebase-document app-name="smart-mes" id="appMaterialCount" path="/data/[[userdata.key]]/appData/material_count" data="[[materialCount]]"></firebase-document>
    <app-localstorage-document key="app-lang" data="{{language}}"></app-localstorage-document>
    <iron-ajax url="data/languages.json" auto handle-as="json" last-response="{{languageItems}}"></iron-ajax>
    <iron-ajax id="requestSampleData" url="data/sample/sample-parallel.json" handle-as="json" verbose="true" last-response="{{sampleData}}"></iron-ajax>
    <ul class="app-grid">
      <li>
        <div class="card">
          <h1 class="title">{{localize('general-settings')}}</h1>
          <vaadin-combo-box label="{{localize('display-language')}}" id="languageSelector" items="[[languageItems]]" name="language selector"
            item-label-path="name" item-value-path="value" value="[[language]]" on-change="changeLanguage" error-message="Invalid input"
            loading="[[!languageItems]]" required always-float-label>
            <template>
              <paper-item>
                <paper-item-body style="min-height: 0">
                  <div>[[item.name]]</div>
                </paper-item-body>
              </paper-item>
            </template>
          </vaadin-combo-box>
          <!-- <p>Connect to device via WebUSB*</p>
          <paper-button on-click="scanDevice" class="btn" title="Search sensor">
            Search Sensor
          </paper-button>
          <paper-button on-click="showDevice" class="btn" title="Show sensor">
            Show Sensor
          </paper-button> -->
          <paper-button on-click="resetOrderCount" class="btn" title="Reset Order Count">
            {{localize('reset-order-count')}}
          </paper-button>
          <paper-toggle-button class="switch" value="[[materialCount]]" on-change="changeMaterialCount" id="materialCountSwitch" noink>Raw Materials Calculation</paper-toggle-button>
        </div>
      </li>
      <li>
        <div class="card">
          <h1 class="title">{{localize('account-settings')}}</h1>
          <paper-input label="{{localize('display-name')}}" id="displayName" value="[[user.displayName]]" type="text" always-float-label></paper-input>
          <paper-button on-click="openBrowseImageFile" class="btn" title="{{localize('upload-profile-image')}}">
            {{localize('change-profile-image')}}
            <input type="file" accept="image/*" name="file" id="uploadImageFile" on-change="_verifyUploadFile" class="inputfile" />
          </paper-button>
          <paper-button on-click="deleteProfileImage" class="btn thunderbird" title="{{localize('remove-profile-image')}}">
            {{localize('remove-profile-image')}}
          </paper-button>
          <paper-button on-click="deleteAccount" class="btn thunderbird" title="{{localize('delete-account')}}">
            {{localize('delete-account')}}
          </paper-button>
          <paper-button on-click="saveAccountSettings" class="btn shamrock" title="{{localize('save-settings')}}">
            {{localize('save-settings')}}
          </paper-button>
        </div>
      </li>
      <li>
        <div class="card">
          <h1 class="title">{{localize('authentication-settings')}}</h1>
          <paper-input label="{{localize('email')}}" id="userEmail" type="email" value="[[user.email]]" always-float-label></paper-input>
          <paper-input label="{{localize('current-password')}}" id="currentPassword" type="password" always-float-label></paper-input>
          <paper-input label="{{localize('new-password')}}" id="newPassword" type="password" always-float-label></paper-input>
          <paper-button on-click="changeEmail" class="btn" title="Change E-mail">
            Change E-mail
          </paper-button>
          <paper-button on-click="changePassword" class="btn" title="{{localize('change-password')}}">
            {{localize('change-password')}}
          </paper-button>
          <paper-button on-click="verifyAccount" class="btn" title="{{localize('verify-account')}}" hidden="[[user.emailVerified]]">
            {{localize('verify-account')}}
          </paper-button>
        </div>
      </li>
      <li>
        <div class="card">
          <h1 class="title">{{localize('backup-settings')}}</h1>
          <p>{{localize('export-or-import-factory-data-to-backup-as-a-file')}}</p>
          <paper-button on-click="exportData" class="btn" title="{{localize('export-data')}}">
            {{localize('export-data')}}
          </paper-button>
          <paper-button on-click="importData" class="btn" title="{{localize('import-data')}}">
            {{localize('import-data')}}
            <input type="file" accept="application/json,.json" name="import-file" id="importFile" />
          </paper-button>
        </div>
      </li>
      <li>
        <div class="card">
          <h1 class="title">{{localize('notification-settings')}}</h1>
          <paper-toggle-button class="switch" value="[[notification]]" on-change="changeNotification" id="webNotificationSwitch" noink>
            {{localize('web-notification')}}</paper-toggle-button>
          <p>{{localize('email-notifcation')}}</p>
          <paper-toggle-button class="switch" value="[[emailAlert]]" on-change="changeEmailAlert" id="emailAlertSwitch" noink>{{localize('email-notification')}}</paper-toggle-button>
          <p>{{localize('user-id')}}: [[user.uid]]</p>
          <!-- <paper-button on-click="openManageUser" class="btn">
            {{localize('manage-users')}}
          </paper-button> -->
        </div>
      </li>
      <li>
        <div class="card">
          <h1 class="title">{{localize('organization-settings')}}</h1>
          <paper-input label="{{localize('company')}}" id="companyName" value="[[userdata.company]]" type="text" always-float-label></paper-input>
          <paper-input label="{{localize('phone-number')}}" id="phoneNumber" value="[[userdata.phone]]" type="tel" maxlength="15"
          pattern="^(\+\d{1,2}\s)?\(?\d{4}\)?[\s]?\d{4}[\s]?\d{1}$" always-float-label></paper-input>
          <div class="meta-data">
            <p>{{localize('data-keychain')}}: [[userdata.key]]</p>
            <p>{{localize('user-role')}}: [[userdata.role]]</p>
          </div>
          <paper-button on-click="openManageKey" class="btn">
            {{localize('manage-keychain')}}
          </paper-button>
          <paper-button on-click="saveOrganizationSettings" class="btn shamrock" title="{{localize('save-settings')}}">
            {{localize('save-settings')}}
          </paper-button>
        </div>
      </li>
    </ul>
    <flat-dialog id="manageKeyDialog" scroll-action="lock">
      <h1 class="center">{{localize('manage-keychain')}}</h1>
      <p>!!WARNNING!! CHANGING KEYCHAIN MIGHT LOST ALL DATA PLEASE BACKUP YOUR KEYCHAIN BEFORE CHANGE THE KEY.</p>
      <vaadin-combo-box id="keyData" label="Data Keychain" items="{{getKeyList(userdata.key)}}" allow-custom-value></vaadin-combo-box>
      <div class="btn-group">
        <paper-button class="btn" dialog-dismiss on-click="closeKeyDialog">
          {{localize('dismiss')}}
        </paper-button>
        <paper-button class="btn shamrock" dialog-confirm autofocus on-click="updateKey">
          {{localize('save')}}
        </paper-button>
      </div>
    </flat-dialog>
    <paper-toast id="toastAlert" always-on-top horizontal-align="right" text="{{localize(toastText)}}"></paper-toast>
  </template>

  <script>
    /**
     * # Settings
     * `<view-settings>` show the settings page of application
     * @ViewSettigns
     * @polymer 
     * @extends {Polymer.Element}
     */
    class ViewSettings extends Polymer.mixinBehaviors([Polymer.AppLocalizeBehavior],Polymer.Element) {
      static get is() {
        return 'view-settings'
      }
      static get properties() {
        return {
          route: Object,
          maxFileSize: {
            type: Number,
            value: 1000000
          },
          language: String,
          notification: Boolean,
          languageItems: Array,
          user: Object,
          appdata: Object,
          emailAlert: Object,
          materialCount: Object,
          statusKnown: Object,
          active: Object,
          pushSupported: Object,
          token: String,
          toastText: String,
          factoryOrderIndex: Object,
          sampleData: Object
        }
      }
      static get observers() {
        return [
          'setKeyValue(userdata.key)'
        ]
      }

      connectedCallback() {
        super.connectedCallback()
        this.loadResources(this.resolveUrl('../data/locales.json'))
        requestAnimationFrame(this._installListeners.bind(this))
      }

      _installListeners() {
        new IMask(this.$.phoneNumber, { mask: "+00 0000 0000 0" });
      }

      resetOrderCount() {
        if (window.confirm('WARNING: Reset order number count to 1 ?')) {
          this.set('factoryOrderIndex.order_count', 1)
        }
      }

      exportData() {
        if (this.appdata) {
          const a = document.createElement('a');
          a.href = 'data:text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(this.appdata));
          a.download = 'export.json';
          a.innerHTML = 'download JSON';
          a.click();
        }
      }

      importData() {
        this.$.importFile.click();
      }

      openManageKey() {
        this.$.manageKeyDialog.opened = true
      }

      closeKeyDialog() {
        this.$.manageKeyDialog.opened = false
      }

      getKeyList(key) {
        if (!key) {
          return [key]
        }
        return [key]
      }

      setKeyValue(key) {
        this.newKey = key;
      }

      updateKey() {
        if (this.newKey) {
          this.$.userData.ref.update({
            key: this.newKey
          }).then(() => {
            this.closeKeyDialog();
            this.toastText = 'notification-save-settings'
            this.$.toastAlert.open()
          }).catch(err => {
            console.error(err.message);
          })
        } else {
          window.alert('Key data cannot be empty.')
        }
      }

      _verifyUploadFile() {
        let file = this.$.uploadImageFile.files[0]
        if (!file.type.match(/image.*/)) {
          this.toastText = 'Invalid file format'
          this.$.toastAlert.open()
          this.$.uploadImageFile.value = null
        } else if (file.size > this.maxFileSize) {
          this.toastText = 'File size maximum is 1 MB'
          this.$.toastAlert.open()
          this.$.uploadImageFile.value = null
        }
      }

      saveAccountSettings() {
        const displayNameInput = this.$.displayName.value
        if (displayNameInput !== '' && displayNameInput !== this.user.displayName) {
          this.user.updateProfile({
            displayName: displayNameInput
          }).then(() => {
            this.toastText = 'notification-save-settings'
            this.$.toastAlert.open()
          })
          this.updateProfileInfo(this.user.photoURL, displayNameInput)
        }
        if (this.$.uploadImageFile.files.length > 0) {
          this.uploadProfileImage()
        }
      }

      saveOrganizationSettings() {
        const companyNameInput = this.$.companyName.value
        const phoneNumberInput = this.$.phoneNumber.value
        if (companyNameInput !== '' && phoneNumberInput !== '') {
          this.$.userData.ref.update({
            company: companyNameInput,
            phone: phoneNumberInput
          }).then(() => {
            this.toastText = 'notification-save-settings'
            this.$.toastAlert.open()
          })
        }
      }

      openBrowseImageFile() {
        this.$.uploadImageFile.click();
      }

      uploadProfileImage() {
        let file = this.$.uploadImageFile.files[0]
        if (file) {
          if (file.type.match(/image.*/) && file.size < this.maxFileSize) {
            let uid = this.user.uid
            let name = this.user.displayName
            let storageRef = this.$.auth.app.storage().ref()
            let metadata = {
              'contentType': file.type
            }
            let imagesRef = storageRef.child('user/' + uid + '/profile')
            imagesRef.put(file, metadata)
              .then(snapshot => {
                let progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
                //this.$.uploadProgress.value = progress
                this.$.uploadImageFile.files.uploading = true
                this.$.uploadImageFile.files.status = snapshot.state
                this.$.uploadImageFile.files.progress = progress
                this.$.uploadImageFile.files.loaded = snapshot.bytesTransferred
                this.$.uploadImageFile.files.size = snapshot.totalBytes
                let url = snapshot.metadata.downloadURLs[0]
                this.user.updateProfile({
                  photoURL: url
                })
                if (url) {
                  this.$.uploadImageFile.files.complete = true
                  this.updateProfileInfo(url, name)
                }
              }).catch((error) => {
                this.$.uploadImageFile.files.error = error
                this.$.uploadImageFile.value = null
                console.error('Upload failed:', error)
              })
          } else {
            this.toastText = 'notification-error-invalid-file-format'
            this.$.toastAlert.open()
            this.$.uploadImageFile.value = null
          }
        }
      }

      updateProfileInfo(url, name) {
        this.$.userData.ref.update({
          displayname: name,
          photoURL: url
        }).then(() => {
          this.$.uploadImageFile.files[0] = null
        }).catch((error) => {
          this.$.uploadImageFile.value = null
        })
      }

      deleteProfileImage() {
        if (this.user.photoURL) {
          if (window.confirm('Delete profile image ?')) {
            let storageRef = firebase.app('smart-mes').storage().ref('user/' + this.user.uid + '/profile')
            // Delete the file
            storageRef.delete()
              .then(() => {
                this.user.updateProfile({
                  photoURL: ""
                })
                this.toastText = 'notification-delete-profile-image-successful'
                this.$.toastAlert.open()
              })
              .catch(error => {
                console.error('Error delete file:', error)
                this.toastText = `Error delete image file ${error} Please try again.`
                this.$.toastAlert.open()
              })
          }
        } else {
          this.toastText = 'notification-no-image-to-delete'
          this.$.toastAlert.open()
        }
      }

      changeLanguage() {
        let selectedLang = this.$.languageSelector.value
        if (selectedLang) {
          if (selectedLang === "us" || selectedLang === "th" || selectedLang === "jp" || selectedLang === "ch" ||
            selectedLang === "ru") {
            this.language = selectedLang
          } else {
            this.language = "us"
          }
        }
      }

      changeMaterialCount() {
        this.set('materialCount', this.$.materialCountSwitch.checked)
        if (this.$.materialCountSwitch.checked) {
          this.toastText = 'notification-material-count-enable'
          this.$.toastAlert.open()
        } else {
          this.toastText = 'notification-material-count-disable'
          this.$.toastAlert.open()
        }
      }

      changeNotification() {
        this.set('notification', this.$.webNotificationSwitch.checked)
        if (this.$.webNotificationSwitch.checked) {
          // Requesting notification permission
        } else {
          this.toastText = 'notification-alert-off'
          this.$.toastAlert.open()
        }
      }

      changeEmailAlert() {
        this.set('emailAlert', this.$.emailAlertSwitch.checked)
        if (this.$.emailAlertSwitch.checked) {
          this.toastText = 'notification-alert-on'
          this.$.toastAlert.open()
        } else {
          this.toastText = 'notification-alert-off'
          this.$.toastAlert.open()
        }
      }

      changeEmail() {
        console.log(this.$.auth.currentUser)
        if(confirm('Are you sure do you want to change this account e-mail ?')) {
          const user = this.$.auth.currentUser
          user.updateEmail(this.$.userEmail.value).then(() => {
            alert('Update E-mail successful. Please re-authen by logout and login again.')
          }).catch((error) => {
            alert('Failed to change E-mail, Please contact administrator.')
          });
        } else {
          this.$.userEmail.value = this.user.email
        }
      }

      changePassword() {
        let currentpassword = this.$.currentPassword.value
        let newPassword = this.$.newPassword.value
        let newemail = this.$.userDataEmail.value
        if (newPassword !== '' && currentpassword !== '') {
          if (this._reauthenAccount(currentpassword)) {
            this.user.updatePassword(newPassword)
              .then(() => {
                this.toastText = 'notification-updated-your-password-successfully'
                this.$.toastAlert.open()
              })
              .catch(err => {
                console.error('Error: ' + err.message)
              })
          } else {
            this.toastText = 'Wrong password'
            this.$.toastAlert.open()
          }
        }

        if (newemail !== '') {
          this.user.updateEmail(newemail)
            .then(() => {
              this.toastText = 'notification-updated-your-email-successfully'
              this.$.toastAlert.open()
            })
            .catch(err => {
              console.error('Error: ' + err.message)
            })
        }
      }

      deleteAccount() {
        if (window.confirm('Delete this account ? Your data will permanently delete.')) {
          let password = prompt("Enter your current password", "");
          if (this._reauthenAccount(password)) {
            this.$.appData.ref.remove();
            this.$.userData.ref.remove();
            this.$.auth.delete().then(() => {
              window.alert("Delete successful, you'll now logout")
              this.logout()
            }).catch((error) => {
              console.error(error)
            })
          } else {
            console.error('Cannot delete account')
          }
        }
      }

      logout() {
        this.$.auth.signOut()
          .then(() => {
            this.authen = false
            // redirect to login page
            this.async(function () {
              this.set('route.path', 'login')
              this.page = 'login'
            }, 500)
          })
          .catch((error) => {
            console.error('%cAuthenticate Failed: ' + error.code, 'color: crimson;')
            this.toastText = `Authenticate Failed: ${error.message} Please try again.`
            this.$.toastAlert.open()
          })
      }

      resetFactoryData() {
        if (window.confirm('This will restore default data ? Your data will permanently replace.')) {
          if (!this.sampleData) {
            const request = this.$.requestSampleData.generateRequest()
            request.completes.then((req) => {
              //console.log(req.response);
              console.info('%cLoaded sample data status:' + req.status + " " + req.statusText,
                'color:green;');
              this.$.factoryData.ref.child(this.userdata.key).set(this.sampleData).catch(error => {
                console.error(error)
              })
            }).catch((rejected) => {
              let req = rejected.request;
              let error = rejected.error;
              console.error("Error requesting data: " + error + " of request " + req);
            })
          }
        }
      }

      scanDevice() {
        if ('usb' in navigator) {
          let device
          device = navigator.usb.requestDevice({
              filters: [{
                vendorId: 0x2341
              }, {
                vendorId: 0x2a03
              }]
            })
            .then(device => {
              console.log(device.productName) // "Arduino Micro"
              console.log(device.manufacturerName) // "Arduino LLC"
            })
            .catch(error => {})
          if (device !== undefined) {
            // Add |device| to the UI.
          }
        } else {
          window.alert('Your web browser is not support physical device detection.')
        }
      }

      showDevice() {
        if ('usb' in navigator) {
          navigator.usb.getDevices().then(devices => {
              devices.map(device => {
                console.log(device.productName) // "Arduino Micro"
                console.log(device.manufacturerName) // "Arduino LLC"
                console.log(device.vendorId) // "Vender ID"
              })
            })
            .catch(error => {
              console.error(error)
            })
        } else {
          window.alert('Your web browser is not support physical device detection. Please use Google Chrome')
        }
      }

      verifyAccount() {
        if (!this.user.emailVerified) {
          this.user.sendEmailVerification()
            .then(() => {
              this.toastText = 'notification-verification-link-has-been-sent-to-your-email'
              this.$.toastAlert.open()
            })
            .catch(err => {
              console.error('Error: ' + err.message)
            })
        }
      }

      _reauthenAccount(currentpassword) {
        const credential = firebase.auth.EmailAuthProvider.credential(this.user.email,
          currentpassword)
        this.user.reauthenticateWithCredential(credential)
          .then(() => {
            return true
          })
          .catch(err => {
            console.error('Error: ' + err.message)
            return false
          })
      }

      handleMessage(message) {
        console.log(message)
        console.log('message received', arguments)
      }
    }
    window.customElements.define(ViewSettings.is, ViewSettings)
  </script>
</dom-module>